package k8s

import (
	"fmt"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes/scheme"
	"k8s.io/apimachinery/pkg/labels"
	"strconv"
	"log"
	"strings"
)

type ReplicaSetDetail struct {
	Name string							`json:"name"`
	Namespace string					`json:"namespace"`
	Labels map[string]string			`json:"labels"`
	Selector map[string]string			`json:"selector"`
	Annotation map[string]string		`json:"annotation"`

	Replicas int32						`json:"replicas"`

	CreateDate string					`json:"createdate"`
	Images []string						`json:"images"`

}

func GetKubernetesReplicaSetDetail(ns string,name string)(replicaset ReplicaSetDetail,podSlce []K8sPod,rsservice []Services,evns []Event,err error)  {
	fmt.Println("begin start get replicas set data")
	rs,_ := clientset.AppsV1().ReplicaSets(ns).Get(name,metav1.GetOptions{

	})
	var images []string
	for _,c := range  rs.Spec.Template.Spec.Containers {
		//fmt.Printf(c.Image)
		images = append(images,c.Image)
	}

	replicaset = ReplicaSetDetail{
		Name:rs.Name,
		Namespace: rs.Namespace,
		Labels: rs.Labels,
		Annotation:rs.Annotations,
		Selector:rs.Spec.Selector.MatchLabels,
		Replicas: *rs.Spec.Replicas,
		CreateDate: rs.CreationTimestamp.Format("2006-01-02 15:03:04"),
		Images: images,

	}

	Selector , _ := metav1.LabelSelectorAsSelector(rs.Spec.Selector)

	fmt.Printf("%+v\n",rs.Spec.Selector)

	pods,_ := clientset.CoreV1().Pods(ns).List(metav1.ListOptions{
		LabelSelector: Selector.String(),
	})
	fmt.Println(len(pods.Items))


	for _,pod := range pods.Items {

		var status string
		if pod.Status.ContainerStatuses[0].State.Terminated != nil {
			status = "Terminated " + pod.Status.ContainerStatuses[0].State.Terminated.Reason
		} else if pod.Status.ContainerStatuses[0].State.Running != nil {
			status = "Running"
		} else if pod.Status.ContainerStatuses[0].State.Waiting != nil {
			status = "Waiting " + pod.Status.ContainerStatuses[0].State.Waiting.Reason
		} else {
			status = "Unknown State ! "
		}

		podSlce = append(podSlce, K8sPod{
			Name:         pod.Name,
			Status:       status,
			//NodeIp:       string(n),
			NodeName: pod.Spec.NodeName,
			PodIp:        pod.Status.PodIP,
			RestartCount: pod.Status.ContainerStatuses[0].RestartCount,
			CreateDate:   pod.CreationTimestamp.Format("2006-01-02 15:04:05"),
		})
	}

	//skip get service from rs describe
	//can not find the method fet the service selector from rs selector

	//tsmap := make(map[string]string,0)
	//for k,v :=  range  rs.Labels {
	//	if k == "pod-template-hash" {
	//		continue
	//	} else {
	//		tsmap[k] = v
	//	}
	//}
	//
	//svcSelector,_ := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{
	//	MatchLabels: tsmap,
	//})

	//fmt.Println(svcSelector.String())

	svcs,_ := clientset.CoreV1().Services(ns).List(metav1.ListOptions{
		LabelSelector: labels.Everything().String(),
	})
	//tttt := metav1.ListOptions{}
	//tttt.

	fmt.Println("svc len is",len(svcs.Items))

	for _,svc := range svcs.Items {
		for k,v := range svc.Spec.Selector {
			if rsValue,ok := rs.Spec.Selector.MatchLabels[k];ok && rsValue == v {

				var epSlice []string
				var labelstr []string
				for k,v := range svc.Spec.Selector {
					tmpstr := k + ": " + v
					labelstr = append(labelstr,tmpstr)
				}

				endpoint,err := clientset.CoreV1().Endpoints(ns).List(metav1.ListOptions{})
				if err != nil {
					log.Println(err.Error())
				}
				var podip []string
				var nodename []string
				for _,ep := range  endpoint.Items {

					if strings.TrimSpace(svc.Name) == strings.TrimSpace(ep.Name) && strings.TrimSpace(ep.Name) != "kubernetes" && len(ep.Subsets) > 0 {
						//后端podIP只取一个，如果多个replics，怎么处理？
						//podip = ep.Subsets[0].Addresses[0].IP //获取service后端podIp
						//nodename = *ep.Subsets[0].Addresses[0].NodeName



						for _,subaddress := range ep.Subsets[0].Addresses {

							podip = append(podip,subaddress.IP)
							nodename = append(nodename,*subaddress.NodeName)
						}

						break    //get 如何传入参数
					}
				}

				//fmt.Println(nodename,podip,"lalalal")

				var internalPort int32
				for _,p := range svc.Spec.Ports {
					if len(nodename) != 0 {
						for i,n := range nodename {
							internalPort = p.Port
							epSlice = append(epSlice, svc.Spec.ClusterIP+":"+strconv.Itoa(int(p.Port))+"→"+podip[i]+":"+p.TargetPort.String()+" ( "+n+" ) ")
						}

					} else {
						//epSlice = append(epSlice, svc.Spec.ClusterIP+":"+strconv.Itoa(int(p.Port))+"→"+podip+":"+p.TargetPort.String())
						epSlice = append(epSlice, "null")
					}
				}
				tmsvc := Services{
					Name: svc.Name,
					Selector: labelstr,
					ClusterIp: svc.Spec.ClusterIP ,
					DomainName:svc.Name + "." + svc.Namespace + fmt.Sprintf(":%d",internalPort),
					EndPoints: epSlice,
					CreateDate: svc.CreationTimestamp.Format("2006-01-02 "),

				}

				rsservice = append(rsservice,tmsvc)


			}
		}
	}



	events, _ := clientset.CoreV1().Events(ns).Search(scheme.Scheme, rs)
	for _,item := range events.Items {

		evns = append(evns,Event{
			//Name: item.Name,
			//Kind: item.InvolvedObject.Kind,
			//
			//
			//Type: item.Type,

			Message: item.Message,
			Source: item.Source.Component + " " + item.Source.Host,
			ChildObject: item.InvolvedObject.FieldPath,
			Reason: item.Reason,
			Num: item.Count,
			LastOccurTime: item.LastTimestamp.Format("2006-01-02 15:04:05"),
		})
	}



	return

}